Skip to main content link. Accesskey S
  • Help
  • HCL Logo
  • HCL Sametime wiki
  • THIS WIKI IS READ-ONLY. Individual names altered for privacy purposes.
  • HCL forums and blogs
  • Home
  • Product Documentation
  • Community Articles
  • Learning Center
Search
Community Articles > Sametime Proxy > Creating a customer service web application using Sametime - Part One
  • Share Show Menu▼
  • Subscribe Show Menu▼

Recent articles by this author

Creating a customer service web application using Sametime - Part Three

Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage ...

Creating a customer service web application using Sametime - Part Two

Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage ...

Creating a customer service web application using Sametime - Part One

Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage ...

Google Chrome extension for Click-to-Call

Make phone calls from any web page: This article describes an extension to the Google Chrome™ browser to allow highlighted phone numbers on an arbitrary web page to be called from Sametime Unified Telephony.

Internet Explorer extension for Click-to-Call

Make phone calls from any web page: This article describes an extension to Microsoft Internet Explorer™ to allow highlighted phone numbers on an arbitrary web page to be called from Sametime Unified Telephony.
Community articleCreating a customer service web application using Sametime - Part One
Added by ~Vanessa Reachek | Edited by ~Kim Rehipigenflar on May 22, 2013 | Version 6
  • Actions Show Menu▼
expanded Abstract
collapsed Abstract
Support Click-to-Chat with only a little coding: The Click-to-Chat pattern is becoming increasingly popular on customer-facing web sites. This series of three articles shows how to implement this using the Sametime Proxy features, with a simple automation servlet, or bot to manage interactions.
Tags: Sametime Proxy, Customer Service Desk
ShowTable of Contents
HideTable of Contents
  • 1 Part 1: Server Side Control
  • 2 How it works
  • 3 The Parts
  • 4 The Servlet
    • 4.1 The HttpServlet class
    • 4.2 The Sametime Bot – the DispatcherBot
    • 4.3 The Sametime Bot – the UserManager
  • 5 Testing the servlet
  • 6 Conclusion
  • 7 Resources
  • 8 About the authors
    • 8.1 Brendan Murray
    • 8.2 William Holmes

Part 1: Server Side Control


The Sametime Proxy SDK can be used to access many of the Sametime features, but it has edge use-cases that, when exploited properly, can make the web experience much more satisfying. This series of articles, along with the associated sample code, illustrates how to create the customer-side interaction, the service agent application, and the bot application running on a server.

How it works


Much of the complexity of the solution is handled automatically by the usual Sametime functionality. This diagram shows what happens:


When the customer clicks on the button, it informs the bot that she requires attention. This information is forwarded to the agent who initiates the chat with the customer. Optionally the agent can call a supervisor into the chat conversation.



The Parts


From the diagram, you can see that this sample solution contains three parts:
  • A customer-facing web application
  • A service-agent web application
  • A servlet/bot that acts to connect the above


  • Programming these parts requires an understanding of both the Sametime Proxy SDK and the Sametime Java server toolkit. We'll explain the choices made, but if you are not familiar with these, you should download the Sametime Toolkit from the link below, and refer to its documentation.

    Of course, we need some predefined data items in the system, in particular the Bot, the group of agents and the group of supervisors. In our example case, we have:


    where the bot has the username servicebot, and we have a group of agents called Support staff, and a group containing supervisors named, unsurprisingly, Supervisors. These three are the main functional participants in our solution.

    The Servlet


    The servlet really has two parts:
    • a class that is a Java EE HttpServlet
    • a class that acts as a Sametime Bot, managing the connection to the Sametime Community server, and a helper class that acts as part of this Sametime Bot, managing the customer support agents and their availability
    From the point of view of Sametime, the bot is just another user: it logs in, creates a watchlist to get user status updates, sends and receives messages, etc.

    Obviously we have to provide a number of parameters in order for this to work:
    • server - the fully-qualified domain name of the Sametime Community Server to which the bot connects.
    • username – the name used by the bot to log in to Sametime. This user must be in the directory, i.e. in LDAP or Active Directory or whatever you usually use as your directory service.
    • password – the password for the bot's user
    • agents – the name of the Sametime public group that contains the names of the agents, i.e. the customer support agents are all members of this group. This allows easy maintenance of the group, where you can add or remove agents as required.
    These parameters could be provided in many ways, such as in the servlet's initialization parameters, in an XML file, or in a properties file. For the sake of simplicity, the sample code uses the initialization parameters. In fact, much of the code is deliberately written in a quite simple style, in order to more clearly illustrate concepts.

    The initialization parameters are stored in the application's web.xml file, in the servlet definition.

    Listing 1: The servlet definition in web.xml

       <servlet>
          <description>
            This takes information about a customer over a REST call,
            and forwards the request to a customer service agent, over the
            Sametime network.
          </description>
          <display-name>ServiceServlet</display-name>
          <servlet-name>ServiceServlet</servlet-name>
          <servlet-class>com.ibm.sametime.sample.ServiceServlet</servlet-class>
          <init-param>
             <description>Sametime Community Server name</description>
             <param-name>server</param-name>
             <param-value>dubxpcvm675.mul.ie.ibm.com</param-value>
          </init-param>
          <init-param>
             <description>Sametime login name</description>
             <param-name>name</param-name>
             <param-value>servicebot</param-value>
          </init-param>
          <init-param>
             <description>Sametime password</description>
             <param-name>password</param-name>
             <param-value>password</param-value>
          </init-param>
          <init-param>
             <description>Support agents' group name</description>
             <param-name>agents</param-name>
             <param-value>Support staff</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>
       </servlet>


    To ensure that the init method is called, it is necessary to specify load-on-startup in the web.xml, as you can see above.

    Of course, we also have to ensure that we can correctly address the servlet, so the servlet-mapping in web.xml defines how to reach the servlet:

    Listing 2: The servlet mapping in web.xml

    <servlet-mapping>
          <servlet-name>ServiceServlet</servlet-name>
          <url-pattern>/ServiceServlet</url-pattern>
       </servlet-mapping>

    The HttpServlet class

    Like any other servlet class, this manages the actual web connectivity of the server. Its function is to respond to a customer's request for assistance which means that it has two functions: it must initialize the Sametime functionality when loaded, by providing an init() function, and it must accept customer requests in doPost(), passing the details on to an available agent.



    Listing 3: The servlet init() method.

    servicebot = new DispatcherBot(getServletConfig().getInitParameter("server"),
                                   getServletConfig().getInitParameter("name"),
                                   getServletConfig().getInitParameter("password"),
                                   getServletConfig().getInitParameter("agents"));


    This code used the init parameters from the web.xml. They could also be provided by another method, such as a properties file or an external xml configuration file

    When a customer requests to chat, the web page will gather some information and forward it to the servlet, where the details are extracted from the request, and then forwarded to the bot code to request that an agent start a chat. The data are sent to the server in the request body of a POST, in order to provide as much security as possible. Note that since this solution is simple, it has no protections against attack.

    The actual POST request sends along the information picked up from the screen. Typically such information will include such things as the customer's name, e-mail address and telephone number, along with a short explanation on why the customer is contacting the agent. In order to uniquely identify the customer as a Sametime user, a unique ID is also sent as one of the parameters. We'll cover this ID later in the section that addresses the customer web pages.

    Listing 4: the doPost() method.

    	// Get the parameters
          String id     = req.getParameter("id");
          String user   = req.getParameter("user");
          String email  = req.getParameter("email");
          String phone  = req.getParameter("phone");
          String reason = req.getParameter("reason");
          
          // Respond to the client
          resp.setContentType("text/html");
          PrintWriter out = resp.getWriter();

          // The only required parameter is the username
          if (null == user || user.length() == 0) {
             out.println("Please fill in the required fields.");
          } else if (servicebot.isLoggedIn()) {
             // If the bot's available display on the web page
             out.println("Request received. Locating agent ...");
             servicebot.alertPartner(id, user, email, phone, reason);
          } else {
             // The bot hasn't initialized – it's an error!
             out.println("Sametime bot not available. Please try again later.");   
             log.fine("DispatcherBot not logged in.");
          }

    The Sametime Bot – the DispatcherBot

    This class manages most of the interaction with Sametime. While it has a number of methods, two in particular are interesting in that they manage the interactions in which we're really interested. The other methods are required by the interfaces and can be considered overhead, and you can read more on these in the Sametime Toolkit documentation. You can add more functionality to these if you want to, but we'll focus on three: the constructor, the loggedIn() and the alertPartner() methods.



    The constructor uses the parameters extracted during the servlet's init() method to establish a connection to Sametime, logging in using the supplied username and password.

    Listing 5: the DispatcherBot constructor


    public DispatcherBot(String serverName, String userId,
                         String password, String agentsGroup) {
       // We need all four parameters
       if (null != serverName && null != userId &&
           null != password && null != agentsGroup) {
          
          m_groupname = agentsGroup;

          try {
             m_stsession = new STSession(this.getClass().getName() + this);
          } catch (DuplicateObjectException e) {
             e.printStackTrace();
             return;
          }

          // Set up the session
          m_stsession.loadSemanticComponents();
          m_stsession.start();

          // get the Community service
          m_commService =
             (CommunityService) m_stsession.getCompApi(CommunityService.COMP_NAME);
          m_commService.addLoginListener(this);

          // Call login
          m_commService.loginByPassword(serverName, userId, password.toCharArray());
       }
    } 


    Once the login has completed, the loggedIn() method is called. At this point the UserManager is instantiated, i.e. the class that handles the list of agents.

    Listing 6: the loggedIn() callback.

    public void loggedIn(LoginEvent e) {
       // Get the support staff names – instantiate the class
       m_userManager = new UserManager(m_groupname, m_stsession);

       // Indicate that we're ready to receive chats
       m_imService = (InstantMessagingService)
                         m_stsession.getCompApi(InstantMessagingService.COMP_NAME);
       m_imService.registerImType(ImTypes.IM_TYPE_CHAT);
       m_imService.addImServiceListener(this);
    }


    The final method of interest is alertPartner(). This method receives the data from the servlet's doPost() and forwards the details to an agent who has been selected by the UserManager. If the bot already has an instant messaging channel open with the agent, it reuses that, otherwise it creates a new one. The data are then sent to the agent in JSON format.

    Note that there is no logic present to handle the situation where no agent is found. In this case you could display a message asking the user to try again later, or some other alternative function.

    Listing 7: the alertPartner() function.

    public void alertPartner(String id, String name, String email,
                                        String phone, String reason) {
       String json = "{ \"id\": \""    + id +
                     "\", \"name\": \""  + name +
                     "\", \"email\":\""  + email +
                     "\", \"phone\":\""  + phone +
                     "\", \"reason\":\"" + reason + "\" }";
       STUser agent = (null == m_userManager)? null
                                             : m_userManager.getNextAvailable();
       // Found an agent?
       if (null != agent) {
          Im im = null;
          Im currentIm = null;

          // See if this agent's IM already exists
          for (int iX=0; iX< m_ImOpened.size(); iX++)
          {
             currentIm = m_ImOpened.elementAt(iX);
             if (currentIm.getPartner().equals(agent)) {
                im = currentIm;
                break;
             }
          }

          // Not found – create a new
          if (null == im) {
             im =  m_imService.createIm(agent, EncLevel.ENC_LEVEL_NONE,
                                               ImTypes.IM_TYPE_CHAT);
             m_ImOpened.addElement(im);
             im.addImListener(this);
             im.open();
          }
          // Send the message
          im.sendText(true, json);
       }
    }


    The Sametime Bot – the UserManager

    The UserManager class looks after the agents and their availability. It adds the members of the agents group to its watchlist, and tracks their status. To do this requires that it support two of the Sametime functions, LookupService and AwarenessService. In reality what it does is identify the members of the group, storing them in an internal table, and then maintaining the individual user's status information in the table. This is a simple solution but not very dynamic. An alternative solution could be to query the a user's status from the watchlist. This would make the solution much more dynamic, but that's an exercise for you to do later.



    While most of the functions in this class are common toolkit functions, the key method we're interested in is getNextAvailable(). The algorithm is very simple, merely selecting the first available agent. This is an area where your own requirements will dictate the algorithm you use. This particular solution will put most of the load on the users who come first in the list, but you may want to ensure an more equitable share of the workload, or use some other criteria to determine who gets selected and when.

    Listing 8: Select an agent

    public STUser getNextAvailable() {
       for (int iX=0; iX<m_supportstaff.size(); iX++)  {
          STWatchedUser user = m_supportstaff.get(iX);
          // User's status “Available” = able to chat to customer
          if (user.getStatus().isStatus(STUserStatus.ST_USER_STATUS_ACTIVE)) {
             log.fine(proc + "- Found: " + user.getDisplayName());
             return user;
          }
       }
       // None available
       return null;
    }


    Testing the servlet


    Of course you'll want to be certain that your code is working as required. The attached sample code has the correct structure to allow you to create a simple WAR to deploy the servlet, although you need to add the stcommsrvrtk.jar from the Sametime server toolkit. It also has a simple web page called testbot.html: replace the string @nowiki@1in this file with the URL of your own server, i.e. where you have deployed the servlet. When you click the Submit button, it should respond with the text “Request received. Locating agent ...”.

    For more detailed information, you can enable logging. The sample code has a number of logging messages which can be enabled in the System Console if you have deployed the servlet on Websphere Application Server. If you have deployed it on a simpler test server such as Apache Tomcat, enabling logging is slightly different, e.g. in Tomcat simply add the following line to your logging.properties file and restart the server:

    Listing 9: Enabling Apache Tomcat logging.

    com.ibm.sametime.sample.level = FINEST


    Conclusion


    In this first part of the series, we covered how to implement the server-side code, where the bot is the customer's only direct contact with the system, providing a little extra security by blocking direct access to the support function.

    The next part of this series will explain how to create the customer and service agent parts of the application.

    Creating a customer service web application using Sametime - Part Two
    Creating a customer service web application using Sametime - Part Three

    Resources


    Sametime Standard V8.5.2 SDK IFR 1 Multiplatform: https://ibm.biz/BdxaNm
    developerWorks® IBM Sametime product page: https://ibm.biz/BdxVZU


    About the authors



    Brendan Murray


    Brendan joined Lotus Development in 1991 and was acquired, along with the rest of the company, by IBM in 1995. Most recently he has been working on Sametime with a particular emphasis on its Web functionality. You can reach him at brendan_murray@ie.ibm.com

    William Holmes


    William has been with IBM since 2007 and is currently the Technical Lead for the Sametime Proxy Web client. You can reach him at HOLMESW@ie.ibm.com

    • Actions Show Menu▼


    expanded Attachments (1)
    collapsed Attachments (1)
    Edit the article to add or modify attachments.
    File TypeSizeFile NameCreated OnDelete file
    application/x-zip 10 KB CustomerServiceDesk-part1.zip 5/7/13, 8:02 PM
    expanded Versions (6)
    collapsed Versions (6)
    Version Comparison     
    VersionDateChanged by              Summary of changes
    This version (6)May 22, 2013, 7:04:41 PM~Kim Rehipigenflar  
    5May 22, 2013, 4:40:25 PM~Sarah Brewevitchynds  
    3May 13, 2013, 8:00:48 PM~Sarah Brewevitchynds  
    1May 13, 2013, 8:00:10 PM~Sarah Brewevitchynds  
    1May 13, 2013, 7:49:02 PM~Sarah Brewevitchynds  
    1May 13, 2013, 7:49:53 PM~Sarah Brewevitchynds  
    expanded Comments (0)
    collapsed Comments (0)
    Copy and paste this wiki markup to link to this article from another article in this wiki.
    Go ElsewhereStay ConnectedAbout
    • HCL Software
    • HCL Digital Solutions community
    • HCL Software Support
    • BlogsDigital Solutions blog
    • Community LinkHCL Software forums and blogs
    • About HCL Software
    • Privacy
    • Accessibility